<?php

namespace app\controller;

use app\BaseController;
use think\facade\Db;
use think\Request;
use app\middleware\Check;

require_once '../sdk/WxpayAPI/lib/WxSend.Api.php';
require_once '../sdk/API-PHP/API_PHP_DEMO.php';

/**
 * Class Order 商户端 支付类控制器
 * @package app\controller
 */
class Pay extends BaseController
{
    protected $middleware = [Check::class];

    /**JsApi支付
     * @return mixed
     * @throws \WxPayException
     */
    public function JsApi()
    {

        require_once '../sdk/WxpayAPI/lib/WxPay.Config.php';
        require_once '../sdk/WxpayAPI/lib/WxPay.Api.php';
        require_once '../sdk/WxpayAPI/example/WxPay.JsApiPay.php';
        $order_no = $this->request->param('order_no');//订单编号
        $openid = $this->request->param('openid');//openidID
        if (empty($order_no)) return jsonFail('缺少订单号');
        if (empty($openid)) return jsonFail('缺少openid');
        $order_list = Db::table('eb_order')
            ->alias('a')
            ->leftJoin('eb_store b', 'a.store_id = b.id')
            ->where('a.order_no', $order_no)
            ->field('b.shop_name,b.send_start,b.send_end,a.total_price')->find();
        $now_time = date("H:i", time());

        if ($now_time >= $order_list['send_start'] && $now_time <= $order_list['send_end']) {
            $money = $order_list['total_price'] * 100;
            $title = $order_list['shop_name'];
            $orders = $order_no;
            $nonce_str = 'hcuasduvihasdiovjerjgvujsaru';
            $tools = new \JsApiPay();
            $input = new \WxPayUnifiedOrder();
            //$input->profit_sharing("Y");//是否需要分账，Y:N
            $input->SetBody($title);//商品描述
            $input->SetAttach($title); //附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用
            $input->SetOut_trade_no($orders);//商户订单号
            $input->SetTotal_fee($money);//订单金额
            $input->SetTime_start(date("YmdHis"));//交易起始时间
            $input->SetTime_expire(date("YmdHis", time() + 600));//交易结束时间
            $input->SetGoods_tag("test"); //订单优惠标记，使用代金券或立减优惠功能时需要的参数，实际上这里可以不要
            $input->SetNotify_url("http://dxsd.jlxmall.com/Pay/notify");//接收回调通知地址
            $input->SetTrade_type("JSAPI"); //支付类型
            $input->SetOpenid($openid);//用户openid
            $order = \WxPayApi::unifiedOrder($input);//统一下单，该方法中包含了签名算法
            $jsApiParameters = $tools->GetJsApiParameters($order);
            //统一下单参数
            //将统一下单接口生成的预支付订单参数返回给前端，前端就可以调取支付了
            return jsonSuccess('操作成功', json_decode($jsApiParameters, true));//getBack是我自定义的方法，就是给前端ajax请求返回json格式数据，1代表成功，这里你要自己修改。
        } else {
            return jsonFail('不在配送时间段，请更改时间段下单哦');
        }
    }

    /**微信退款
     * @param Request $request
     */
    public function refund(Request $request)
    {
        require_once '../sdk/WxpayAPI/lib/WxPay.Config.php';
        require_once '../sdk/WxpayAPI/lib/WxPay.Api.php';
        require_once '../sdk/WxpayAPI/example/WxPay.JsApiPay.php';
        $order_no = $this->request->param('order_no');//订单编号
//        $openid = $this->request->param('openid');//openidID
        $money = $this->request->param('money');//商家退款金额
        $type = $this->request->param('type');//1：取消订单 2：商家退款
        if (empty($order_no) || is_null($type)) return jsonFail('缺少参数');
        //查询订单,根据订单里边的数据进行退款
        $order = Db::table('eb_order')->where('order_no', $order_no)->find();
        if (!is_null($order['send_id']) && $order['status'] != -1) return jsonFail('订单不可退单');
        if ($type == 2 && $order['goods_price'] < $money) return jsonFail('退款费用大于商品费用，请检查金额');
        $send = new \API_PHP_DEMO();
        $store = Db::table('eb_store')->where('id', $order['store_id'])->find();
        $order_list = Db::table('eb_order_detail')->alias('a')
            ->leftJoin('eb_goods b', 'a.goods_id = b.id')
            ->where('a.order_id', $order['id'])
            ->field('a.*,b.*')
            ->select()->toArray();
        try {
            if ($order['pay_type'] == 1 && $type == 1) {//余额支付并且取消订单
                Db::startTrans();
                $ress = Db::table('eb_order')->where('order_no', $order_no)->update(['status' => -2]);
                if ($order['pid'] != 0) {//有上级
                    $res = Db::table('eb_user')->where('id', $order['pid'])
                        ->dec('integral', $order['pid_price'])
                        ->update();
                }
                $res = Db::table('eb_user')->where('id', $order['user_id'])
                    ->inc('integral', $order['goods_price'])
                    ->update();
                $data = combination_cancel($money, $store, $order, $order_list, 14, 6, 3, 6);
                $code = $send->printMsg($store['sn'], $data);
                $datas = json_decode($code, true);
                if ($res != 0) {
                    Db::commit();
                    return jsonSuccess('退款成功');
                } else {
                    Db::rollback();
                    return jsonFail('退款失败');
                }

            } else if ($order['pay_type'] == 1 && $type == 2) {//余额支付并且协商退款
                Db::startTrans();
                $ress = Db::table('eb_order')->where('order_no', $order_no)->update(['status' => -2]);
                if ($order['pid'] != 0) {//有上级
                    $res = Db::table('eb_user')->where('id', $order['pid'])
                        ->dec('integral', $order['pid_price'])
                        ->update();
                }
                $res = Db::table('eb_user')->where('id', $order['user_id'])
                    ->inc('integral', $money)
                    ->update();
                $data = combination_cancel($money, $store, $order, $order_list, 14, 6, 3, 6);
                $code = $send->printMsg($store['sn'], $data);
                $datas = json_decode($code, true);
                if ($res != 0 && $datas['ret'] == 0) {
                    Db::commit();
                    return jsonSuccess('退款成功');
                } else {
                    Db::rollback();
                    return jsonFail('退款失败');
                }
            }
            $merchid = \WxPayConfig::MCHID;
            if (!$order_no) return jsonFail('order不能为空');
            $input = new \WxPayRefund();
            $input->SetOut_trade_no($order_no);   //自己的订单号
            $input->SetTransaction_id($order['transaction_id']);  //微信官方生成的订单流水号，在支付成功中有返回
            $input->SetOut_refund_no(create_order_no());   //退款单号
            $input->SetTotal_fee($order['total_price'] * 100);   //订单标价金额，单位为分
            if ($type == 1) {
                $input->SetRefund_fee($order['total_price'] * 100);   //退款总金额，订单总金额，单位为分，只能为整数
            } else {
                $input->SetRefund_fee($money * 100);   //退款总金额，订单总金额，单位为分，只能为整数
            }
            $input->SetOp_user_id($merchid);
            $result = \WxPayApi::refund($input); //退款操作
            if (($result['return_code'] == 'SUCCESS') && ($result['result_code'] == 'SUCCESS')) {
                if ($type == 1) {//取消订单
                    Db::startTrans();
                    $res = Db::table('eb_order')->where('order_no', $order_no)->update(['status' => -4]);
                    if ($order['pid'] != 0) {//有上级
                        Db::table('eb_user')->where('id', $order['pid'])
                            ->dec('integral', $order['pid_price'])
                            ->update();
                    }
                    $data = combination_cancel($money, $store, $order, $order_list, 14, 6, 3, 6);
                    $code = $send->printMsg($store['sn'], $data);
                    $datas = json_decode($code, true);
                    if ($res != 0) {
                        Db::commit();
                        return jsonSuccess('退款成功');
                    }
                    Db::rollback();
                    return jsonFail('退款失败');
                } else {//-2同意退款
                    Db::startTrans();
                    $store_price = $order['goods_price'] - $money;//划给商家
                    $plat_price = $order['delivery_price'];//划给平台
                    $res = Db::table('eb_order')->where('order_no', $order_no)->update(['status' => -2, 'plat_price' => $plat_price, 'store_price' => $store_price, 'delivery_price' => 0]);
                    if ($order['pid'] != 0) {//有上级
                        Db::table('eb_user')->where('id', $order['pid'])
                            ->dec('integral', $order['pid_price'])
                            ->update();
                    }
                    $send = new \WxSendApi();
                    $ds = json_decode($send->send_Template_Refuse_rider($order['send_id'], $order), true);
                    if ($ds['ret'] == 0) {
                        Db::commit();
                        return jsonSuccess('退款成功');
                    } else {
                        Db::rollback();
                        return jsonFail('退款失败');
                    }
                }
            } else if (($result['result_code'] == 'FAIL')) {//订单不存在
                //退款失败
                return jsonFail($result['err_code_des']);
            } else {
                //失败
                return jsonFail('未知错误');
            }
        } catch (\Exception $e) {
            return jsonFail($e->getMessage());
        }
    }

    //回调处理
    public function notify()
    {
        header('Content-Type:text/json;charset=utf-8');
        echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        ini_set('date.timezone', 'Asia/Shanghai');
        error_reporting(E_ERROR);
        //初始化日志
        require_once '../sdk/WxpayAPI/lib/WxPay.Config.php';
        require_once '../sdk/WxpayAPI/example/log.php';
        $logHandler = new \CLogFileHandler(app_path() . 'sdk/WxpayAPI/logs/' . date('Y-m-d') . '.log');
        $log = \Log::Init($logHandler, 15);
        $xml = $this->postdata();
        \Log::DEBUG("$xml");
        //日志记录接收到的数据
        \Log::DEBUG("begin notify");
        \Log::DEBUG("$xml");
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $obj = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        ksort($obj);
        $str = $this->ToUrlParams($obj);
        $string = $str . "&key=" . \WxPayConfig::KEY;
        $user_sign = strtoupper(md5($string));
        if ($user_sign == $obj['sign']) {
            \Log::DEBUG("回调签名验证成功");
            //验证成功
            $order = $obj['out_trade_no'];//订单号
            $userid = $obj['openid'];//用户id
            $attach = $obj['attach'];//商品名称
            $money = $obj['total_fee'] / 100;//金额
            $transaction_id = $obj['transaction_id'];//微信支付订单号
            //更新用户账号余额
            $order_info = Db::table('eb_order')->where('order_no', $order)->find();
            $operate_info = Db::table('eb_admin')->where('id', $order_info['operate_id'])->find();
            $regus_time = time() + $operate_info['send_delaytime'] * 60;
            try {
                Db::startTrans();
                Db::table('eb_order')->where('order_no', $order)->update(['is_pay' => 1, 'transaction_id' => $transaction_id, 'status' => 1, 'regus_time' => $regus_time,]);
                if ($order['pid'] != 0) {//有上级
                    Db::table('eb_user')->where('id', $order_info['pid'])
                        ->inc('integral', $order_info['pid_price'])
                        ->update();
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
            }

            $dormitory_info = Db::table('eb_dormitory')->where('id', $order_info['dormitory_id'])->find();
            //通知商家待定---------
            $store = Db::table('eb_store')->where('id', $order_info['store_id'])->find();
            $user_list = Db::table('eb_user')->alias('a')
                ->leftJoin('eb_school b', 'a.school_id = b.id')
                ->field('b.name as school_name')
                ->where('a.id', $order_info['user_id'])->find();
            $order_list = Db::table('eb_order_detail')
                ->alias('a')
                ->leftJoin('eb_goods b', 'a.goods_id = b.id')
                ->where('a.order_id', $order_info['id'])
                ->field('a.*,b.*')
                ->select()->toArray();
            $send = new \API_PHP_DEMO();
            $data = combination($store, $user_list, $order_info, $order_list, 14, 6, 3, 6);
            $code = $send->printMsg($store['sn'], $data);
            //通知骑手
            $list = Db::table('eb_user')->where('school_id', $order_info['school_id'])->where('delivery_type', 0)->where('type', '<>', 1)->select()->toArray();
            $sends = new \WxSendApi();
            foreach ($list as $key => $value) {
                $delivery_storieds = explode(',', $value['delivery_storied']);
                if (in_array($order_info['dormitory_id'], $delivery_storieds)) {
                    $sends->send_Template_rider($value, $order_info);//通知骑手
                }
            }
        }
    }

    /*
     * 接收post数据
    */
    public function postdata()
    {
        $receipt = file_get_contents("php://input");
        return $receipt;
    }

    /**
     * 格式化参数格式化成url参数
     */
    public function ToUrlParams($value)
    {
        $buff = "";
        foreach ($value as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
}
